#pragma once
#include <vector>
#include "util.hpp"
#include <cassert>

namespace log
{
#define DEFAULT_BUFFER_SIZE (1 * 1024 * 1024)
#define THRESHOLD_BUFFER_SIZE (8 * 1024 * 1024) // 扩容的阈值
#define INCREMENT_BUFFER_SIZE (1 * 1024 * 1024)
  class Buffer
  {
  public:
    Buffer() : _buffer(DEFAULT_BUFFER_SIZE), _reader_idx(0), _writer_idx(0)
    {
    }

    bool empty()
    {
      return (_reader_idx == _writer_idx);
    }

    void push(const char *data, size_t len)
    {
      // 将数据拷贝到缓冲区中

      ensureEnoughSize(len);

      // 将数据从data 到data+len的位置拷贝到_buffer中
      std::copy(data, data + len, &_buffer[_writer_idx]);

      MoveWriter(len);
    }

    // 返回可读数据的起始位置
    const char *begin()
    {
      return &_buffer[_reader_idx];
    }

    // 返回可读数据的长度
    size_t readAbleSize()
    {
      return (_writer_idx - _reader_idx);
    }

    //这个函数是对固定大小缓冲区的大小，  因为有扩容机制，不存在可写固定大小，因为总是可写
    size_t writeAbleSize()
    {
      return (_buffer.size() - _writer_idx);
    }

    // 重置读写位置，初始化缓冲区
    void reset()
    {
      _writer_idx = 0;
      _reader_idx = 0;
    }

    void swap(Buffer &buffer)
    {
      _buffer.swap(buffer._buffer);
      std::swap(_reader_idx, buffer._reader_idx);
      std::swap(_writer_idx, buffer._writer_idx);
    }

    void MoveReader(size_t len)
    {
      assert(len <= readAbleSize());

      _reader_idx += len;
    }

    void MoveWriter(size_t len)
    {
      // assert((_writer_idx + len) <= _buffer.size());

      _writer_idx += len;
    }

  private:
    void ensureEnoughSize(size_t len)
    {
      if (len <= writeAbleSize())
        return;

      size_t new_size = 0;
      if (_buffer.size() < THRESHOLD_BUFFER_SIZE)
      {
        new_size = _buffer.size() * 2;
      }
      else
      {
        new_size = _buffer.size() + INCREMENT_BUFFER_SIZE;
      }

      _buffer.resize(new_size);
    }

  private:
    std::vector<char> _buffer;
    size_t _reader_idx; // 当前可读数据的指针
    size_t _writer_idx; // 当前可写数据的指针
  };

}